home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 7 / Apprentice-Release7.iso / Source Code / Libraries / Aidan's Class Libraries / Source / Headers / Templates / Lists.cpp next >
Encoding:
Text File  |  1997-05-24  |  10.3 KB  |  431 lines  |  [TEXT/CWIE]

  1. //Copyright (c) 1997 Aidan Cully
  2. //All rights reserved
  3.  
  4. //TList::TData::TData()
  5. //    uses:
  6. //        Used internally by TList and TData to initialize the data contained
  7. //        in a TData structure
  8. //    in:
  9. //        none
  10. //    out:
  11. //        none
  12. //    side effects:
  13. //        TList::TData is initialized
  14. template <class T>
  15. TData<T>::TData( T item ):
  16.     mData( item )
  17. {
  18.     mNext = 0l;
  19.     mPrev = 0l;
  20. }
  21.  
  22. //TList::TData::AddPrev()
  23. //    uses:
  24. //        Used internally by TList to maintain the structure of the list
  25. //    in:
  26. //        none
  27. //    out:
  28. //        returns Boolean
  29. //            TRUE: an element could be added
  30. //            FALSE: an element could not be added
  31. //    side effects:
  32. //        A new element is placed after the current one in the TList's data linked list
  33. template <class T>
  34. Boolean TData<T>::AddNext( T item )
  35. {
  36.     //Is there an element already after this one?
  37.     if( !mNext ) {
  38.         //No, so we just have to create a new one and initialize it
  39.         mNext = new TData( item );
  40.         if( !mNext )
  41.             return( false );
  42.         mNext->mPrev = this;
  43.     } else {
  44.         //Yes, so we have to keep track of the old element
  45.         TData *oldNext = mNext;
  46.         //Now we can create and initialize the new element
  47.         mNext = new TData( item );
  48.         if( !mNext )
  49.             return( false );
  50.         mNext->mNext = oldNext;
  51.         oldNext->mPrev = mNext;
  52.         mNext->mPrev = this;
  53.     }
  54.     return( true );
  55. }
  56.  
  57. //TList::TData::AddPrev()
  58. //    uses:
  59. //        Used internally by TList to maintain the structure of the list
  60. //    in:
  61. //        none
  62. //    out:
  63. //        returns Boolean
  64. //            TRUE: an element could be added
  65. //            FALSE: an element could not be added
  66. //    side effects:
  67. //        A new element is placed before the current one in the TList's data linked list
  68. template <class T>
  69. Boolean TData<T>::AddPrev( T item )
  70. {
  71.     //Is there an element already before us?
  72.     if( !mPrev ) {
  73.         //No, so all we have to do is create a new element there
  74.         //and initialize it's data properly
  75.         mPrev = new TData( item );
  76.         if( !mPrev )
  77.             return( false );
  78.         mPrev->mNext = this;
  79.     } else {
  80.         //Yes, so make sure we don't lose track of the old element
  81.         TData *oldPrev = mPrev;
  82.         //Create and initialize the old elements
  83.         mPrev = new TData( item );
  84.         if( !mPrev )
  85.             return( false );
  86.         mPrev->mPrev = oldPrev;
  87.         oldPrev->mNext = mPrev;
  88.         mPrev->mNext = this;
  89.     }
  90.     return( true );
  91. }
  92.  
  93. //TList::TList()
  94. //    uses:
  95. //        This is the TList constructor.
  96. //    in:
  97. //        none
  98. //    out:
  99. //        none
  100. //    side effects:
  101. //        mNode is initialized to 0
  102. template <class T>
  103. TList<T>::TList():
  104.     mNode( 0 )
  105. {
  106. }
  107.  
  108. //TList::~TList()
  109. //    uses:
  110. //        This is the TList destructor.  It cleans up any memory allocated by the TList during
  111. //        the course of its use
  112. //    in:
  113. //        none
  114. //    out:
  115. //        none
  116. //    side effects:
  117. //        all the data elements are officially dead
  118. template <class T>
  119. TList<T>::~TList()
  120. {
  121.     //Is there data?
  122.     if( MoveFirst() )
  123.         //Then get rid of it!
  124.         while( Remove() )
  125.             ;
  126. }
  127.  
  128. //TList::AddPrev()
  129. //    uses:
  130. //        Call this function to add a new element before the current one in the TList
  131. //    in:
  132. //        none
  133. //    out:
  134. //        returns Boolean
  135. //            true if a new element could be added
  136. //            false if a new element could not be added
  137. //    side effects:
  138. //        A new element is inserted before the current one, and the new element becomes the
  139. //        current element.
  140. template <class T>
  141. Boolean TList<T>::AddPrev( T item )
  142. {
  143.     //Do we have a place to store the data?
  144.     if( !mNode ) {
  145.         //No, so we have to create one
  146.         mNode = new TData<T>( item );
  147.         if( !mNode )
  148.             return( false );
  149.     } else {
  150.         //Yes, so we have to tack on to it
  151.         if( !mNode->AddPrev( item ) )
  152.             return( false );
  153.         mNode = mNode->mPrev;
  154.     }
  155.     return( true );
  156. }
  157.  
  158. //TList::AddNext()
  159. //    uses:
  160. //        Call this function to add a new element after the current one in the TList
  161. //    in:
  162. //        none
  163. //    out:
  164. //        returns Boolean
  165. //            true if a new element could be added
  166. //            false if a new element could not be added
  167. //    side effects:
  168. //        A new element is inserted after the current one, and the new element becomes the
  169. //        current element.
  170. template <class T>
  171. Boolean TList<T>::AddNext( T item )
  172. {
  173.     //Do we have a place to store the data?
  174.     if( !mNode ) {
  175.         //No, so we have to create one
  176.         mNode = new TData<T>( item );
  177.         if( !mNode )
  178.             return( false );
  179.     } else {
  180.         //Yes, so we have to tack on to it
  181.         if( !mNode->AddNext( item ) )
  182.             return( false );
  183.         mNode = mNode->mNext;
  184.     }
  185.     return( true );
  186. }
  187.  
  188. //TList::MovePrev()
  189. //    uses:
  190. //        Use this function to set the current element to the element just before the present
  191. //        current element
  192. //    in:
  193. //        none
  194. //    out:
  195. //        returns Boolean
  196. //            true if the current element could be moved
  197. //            false if the current element could not be moved
  198. //    side effects:
  199. //        The current element is changed to the element just before the present current element
  200. template <class T>
  201. Boolean TList<T>::MovePrev()
  202. {
  203.     if( !mNode )
  204.         return( false );
  205.     if( !mNode->mPrev )
  206.         return( false );
  207.     mNode = mNode->mPrev;
  208.     return( true );
  209. }
  210.  
  211. //TList::MoveNext()
  212. //    uses:
  213. //        Use this function to set the current element to the element just after the present
  214. //        current element
  215. //    in:
  216. //        none
  217. //    out:
  218. //        returns Boolean
  219. //            true if the current element could be moved
  220. //            false if the current element could not be moved
  221. //    side effects:
  222. //        The current element is changed to the element just after the present current element
  223. template <class T>
  224. Boolean TList<T>::MoveNext()
  225. {
  226.     if( !mNode )
  227.         return( false );
  228.     if( !mNode->mNext )
  229.         return( false );
  230.     mNode = mNode->mNext;
  231.     return( true );
  232. }
  233.  
  234. //TList::MoveFirst()
  235. //    uses:
  236. //        Sets the current element to the first element in the list
  237. //    in:
  238. //        none
  239. //    out:
  240. //        returns Boolean
  241. //            true if there are elements in the list
  242. //            false if the list contains no elements
  243. //    side effects:
  244. //        The current element now points to the beginning of the list
  245. template <class T>
  246. Boolean TList<T>::MoveFirst()
  247. {
  248.     //Is there data?
  249.     if( !mNode )
  250.         return( false );
  251.     //Go back as far as we can
  252.     while( MovePrev() )
  253.         ;
  254.     return( true );
  255. }
  256.  
  257. //TList::MoveLast()
  258. //    uses:
  259. //        Sets the current element to the first last in the list
  260. //    in:
  261. //        none
  262. //    out:
  263. //        returns Boolean
  264. //            true if there are elements in the list
  265. //            false if the list contains no elements
  266. //    side effects:
  267. //        The current element now points to the end of the list
  268. template <class T>
  269. Boolean TList<T>::MoveLast()
  270. {
  271.     //Is there data?
  272.     if( !mNode )
  273.         return( false );
  274.     //Go as far forward as we can
  275.     while( MoveNext() )
  276.         ;
  277.     return( true );
  278. }
  279.  
  280. //TList::GetData()
  281. //    uses:
  282. //        Use this function to find out what data is held in the current element of the list
  283. //    in:
  284. //        none
  285. //    out:
  286. //        UInt32 data
  287. //            This value is filled in with the current data in the list
  288. //        returns Boolean
  289. //            true if there is data in the list
  290. //            false if the list contains no data
  291. //    side effects:
  292. //        data is set to the data pointed to by the current element in the list
  293. template <class T>
  294. Boolean TList<T>::GetData( T &data )
  295. {
  296.     if( !mNode )
  297.         return( false );
  298.     data= mNode->mData;
  299.     return( true );
  300. }
  301.  
  302. //TList::SetData()
  303. //    uses:
  304. //        Use this function to set the data held in the current element of the list
  305. //    in:
  306. //        UInt32 data
  307. //            This value contains what we want the data in the list to look like
  308. //    out:
  309. //        returns Boolean
  310. //            true if there is storage for the data
  311. //            false if there is no storage
  312. //    side effects:
  313. //        The data pointed to by the current list element is overwritten by the value passed
  314. template <class T>
  315. Boolean TList<T>::SetData( T newData )
  316. {
  317.     if( !mNode )
  318.         return( false );
  319.     mNode->mData= newData;
  320.     return( true );
  321. }
  322.  
  323. //TList::GoToElem()
  324. //    uses:
  325. //        Used to set the current element of the list to an |absolute value|, rather than
  326. //        always changing the value relative to the current one.  Usually used in conjunction
  327. //        with TList::FindIndex()
  328. //    in:
  329. //        SInt16 theIndex
  330. //            This is the absolute index of the element you want the list to point to
  331. //    out:
  332. //        returns Boolean
  333. //            true if theIndex is within the bounds of the list
  334. //            false if theIndex is not within the bounds of the list
  335. //    side effects:
  336. //        The list's current element is set to theIndex'th element in the list.
  337. template <class T>
  338. Boolean TList<T>::GoToElem( SInt16 theIndex )
  339. {
  340.     if( !MoveFirst() )
  341.         return( false );
  342.     if( theIndex < 0 )
  343.         return( false );
  344.     while( theIndex-- )
  345.         if( !MoveNext() )
  346.             return( false );
  347.     return( true );
  348. }
  349.  
  350. //TList::FindIndex()
  351. //    uses:
  352. //        Used for searching a list for an element with particular data
  353. //    in:
  354. //        UInt32 theData
  355. //            The data we are looking for
  356. //    out:
  357. //        returns SInt16
  358. //            On success, returns the index of the element in the array.
  359. //            -1 if theData does not exist in the list
  360. //    side effects:
  361. //        Don't rely on any.  If you want to use this index, use the function TList::GoToElem()
  362. template <class T>
  363. SInt16 TList<T>::FindIndex( T theData )
  364. {
  365.     SInt16 theIndex = 0;
  366.     T temp;
  367.  
  368.     if( !MoveFirst() )
  369.         //There is no data!  AAaargh!
  370.         return( -1 );
  371.     GetData( temp );
  372.     //Loop through every element until we find theData.
  373.     while( temp != theData )
  374.         if( MoveNext() ) {
  375.             theIndex++;
  376.             GetData(temp);
  377.         } else
  378.             //Didn't find it.
  379.             return( -1 );
  380.     //If the data didn't exist, we wouldn't have gotten this far.
  381.     return( theIndex );
  382. }
  383.  
  384. //TList::Remove()
  385. //    uses:
  386. //        Used to free up the memory held by the current element in the array.  The current
  387. //        element is set to the current next if available, otherwise to the current previous.
  388. //        If neither is available, there is no current element.
  389. //    in:
  390. //        none
  391. //    out:
  392. //        returns Boolean
  393. //            true if there is still data in the list
  394. //            false if the list contains no data
  395. //    side effects:
  396. //        the present current element is no more, and instead it points to the present next
  397. //        element if available, otherwise it points to the current previous element.  If neither
  398. //        is available, there is no current element.
  399. template <class T>
  400. Boolean TList<T>::Remove()
  401. {
  402.     //What is the situation here?
  403.     if( !mNode )
  404.         //No data, return false
  405.         return( false );
  406.     if( !(mNode->mPrev || mNode->mNext) ) {
  407.         //This is the only element in the list, don't have to worry about losing track
  408.         //of the previous/next.
  409.         delete mNode;
  410.         mNode = 0l;
  411.     } else if( !mNode->mNext ) {
  412.         //There is no next element, so we set the current element back one
  413.         mNode = mNode->mPrev;
  414.         delete mNode->mNext;
  415.         mNode->mNext = 0l;
  416.     } else {
  417.         //There is a next element, keep track of it.
  418.         TData<T> *oldNode = mNode;
  419.         mNode = mNode->mNext;
  420.         //Is there a previous element?
  421.         if( oldNode->mPrev ) {
  422.             //Yes, so we have to make sure the mNext/mPrev's point to the right place
  423.             mNode->mPrev = oldNode->mPrev;
  424.             oldNode->mPrev->mNext = mNode;
  425.         } else
  426.             //No, so we don't have to worry about the previous node
  427.             mNode->mPrev = 0l;
  428.         delete oldNode;
  429.     }
  430.     return( true );
  431. }